/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC

/* USER CODE BEGIN Private defines */
extern  TIM_HandleTypeDef htim1;
extern  TIM_HandleTypeDef htim3;
#define UART_DMATX_INIT(uart, dma, dmach_tx)                        \
do                                                                  \
{                                                                   \
    LL_USART_ClearFlag_TC(uart);                                    \
    LL_USART_EnableDMAReq_TX(uart);                                 \
    LL_DMA_SetPeriphAddress(dma, dmach_tx, (uint32_t)(&uart->TDR)); \
} while (0)

#define UART_DMARX_INIT(uart, dma, dmach_rx, rxbuffer)              \
do                                                                  \
{                                                                   \
    LL_USART_ClearFlag_IDLE(uart);                                  \
    LL_USART_EnableDMAReq_RX(uart);                                 \
    LL_DMA_SetPeriphAddress(dma, dmach_rx, (uint32_t)(&uart->RDR)); \
    LL_DMA_DisableChannel(dma, dmach_rx);                           \
    LL_DMA_SetMemoryAddress(dma, dmach_rx, (uint32_t)rxbuffer);     \
    LL_DMA_SetDataLength(dma, dmach_rx, sizeof(rxbuffer));          \
    LL_DMA_EnableChannel(dma, dmach_rx);                            \
} while (0)

#define UART_TX(dma, dmach_tx, txbuffer, txlen)                     \
    do                                                              \
    {                                                               \
        LL_DMA_DisableChannel(dma, dmach_tx);                       \
        LL_DMA_ClearFlag_TC2(dma);                                  \
        LL_DMA_ClearFlag_TE2(dma);                                  \
        LL_DMA_SetMemoryAddress(dma, dmach_tx, (uint32_t)txbuffer); \
        LL_DMA_SetDataLength(dma, dmach_tx, txlen);                 \
        LL_DMA_EnableChannel(dma, dmach_tx);                        \
    } while (0)

#define UART_RX(uart, dma, dmach_rx, rxbuffer, on_recive, on_no_data) \
    do                                                                \
    {                                                                 \
        if (LL_USART_IsActiveFlag_FE(uart))                           \
            LL_USART_ClearFlag_FE(uart);                              \
        if (LL_USART_IsActiveFlag_ORE(uart))                          \
            LL_USART_ClearFlag_ORE(uart);                             \
        if (LL_USART_IsActiveFlag_NE(uart))                           \
            LL_USART_ClearFlag_NE(uart);                              \
        if (LL_USART_IsActiveFlag_PE(uart))                           \
            LL_USART_ClearFlag_PE(uart);                              \
        if (LL_USART_IsActiveFlag_CM(uart))                           \
            LL_USART_ClearFlag_CM(uart);                              \
        if (LL_USART_IsActiveFlag_IDLE(uart))                         \
            LL_USART_ClearFlag_IDLE(uart);                            \
        int32_t remain = LL_DMA_GetDataLength(dma, dmach_rx);         \
        LL_DMA_DisableChannel(dma, dmach_rx);                         \
        if (remain >= 0 && remain <= sizeof(rxbuffer))                \
        {                                                             \
            int32_t datalen = sizeof(rxbuffer) - remain;              \
            if (datalen > 0)                                          \
            {                                                         \
                on_recive;                                            \
            }                                                         \
        }                                                             \
        else                                                          \
        {                                                             \
            on_no_data;                                               \
        }                                                             \
        LL_DMA_SetMemoryAddress(dma, dmach_rx, (uint32_t)rxbuffer);   \
        LL_DMA_SetDataLength(dma, dmach_rx, sizeof(rxbuffer));        \
        LL_DMA_ClearFlag_TE1(dma);                                    \
        LL_DMA_ClearFlag_TC1(dma);                                    \
        LL_DMA_EnableChannel(dma, dmach_rx);                          \
    } while (0)

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */
